<?php

namespace App\Providers;

use App\Rules\BaseRule;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\ServiceProvider;

class ScarecrowValidatorProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
    }

    /**
     * register validator list
     */
    public function boot()
    {
        $allRuleList = $this->getAllExtendRule();
        $this->registerExtendRule($allRuleList);
    }

    /**
     * 注册扩展规则
     * @param $allRuleList
     */
    protected function registerExtendRule($allRuleList) {
        foreach ($allRuleList as $filePath => $fileName) {
            $ruleName = strtolower(mb_substr($fileName, 0, mb_strlen($fileName) - 4));
            $className = 'App\\Rules\\' . $fileName;
            Validator::extend($ruleName, function ($attribute, $value, $parameters, $validator) use($className) {
                $obj = new $className;
                if ($obj instanceof BaseRule) {
                    return $obj->passes($attribute, $value, $parameters, $validator);
                }
                return false;
            });
            Validator::replacer($ruleName, function ($message, $attribute, $rule, $parameters) use($className, $ruleName)  {
                $obj = new $className;
                if ($obj instanceof BaseRule) {
                    if ($message == "validation.{$ruleName}") {
                        return $obj->message($attribute, $rule, $parameters);
                    }
                    return $message;
                }

                return $message;
            });
        }
    }

    /**
     * 获取所有的扩展规则
     * @return array
     */
    protected function getAllExtendRule() {
        $basePath = base_path('app/Rules');
        if (!is_dir($basePath)) {
            return [];
        }

        ['dir'=>$dirs, 'file'=>$files] = ReadAllDirAndFiles($basePath);

        $needRegisterFileList = [];
        foreach ($files as $filePath) {
            $fileInfo = $this->checkFileIsRule($filePath);
            if ($fileInfo['code'] == 0) {
                $needRegisterFileList[$filePath] = $fileInfo['fileName'];
            }
        }
        return $needRegisterFileList;
    }

    /**
     * 检测文件是否是规则文件
     * @param $filePath
     * @return bool
     */
    protected function checkFileIsRule($filePath) {
        $filePath = str_replace('\\', '/', $filePath);
        if (preg_match('/(.*)\/(.+Rule)\.php$/s', $filePath, $arr)) {
            $fileName = $arr[2];
            if ($fileName == "BaseRule") {
                return ['code'=>1, 'fileName'=>''];
            }
            return ['code'=>0, 'fileName'=>$fileName];
        } else {
            return ['code'=>1, 'fileName'=>''];
        }
    }
}
